@file:Suppress("unused", "Deprecation")

package com.hjh.tool.util

import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build

/**
 * @author： hjh
 * @createDate： 2025/5/9 17:43
 * @description：手动切换和指定使用 4G 或以太网网络
 * @qq： 3472903821
 * @version: 1.0
 */
@SuppressLint("ObsoleteSdkInt")
class NetworkSwitcher(private val context: Context) {

    private val connectivityManager: ConnectivityManager by lazy {
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    }

    /**
     * 网络信息数据结构，包含网络对象和类型
     */
    data class NetworkInfo(val network: Network, val type: NetworkQueryHelper.NetworkType)

    /**
     * 获取当前活跃网络类型
     */
    fun getActiveNetworkType(): NetworkQueryHelper.NetworkType? {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return null
        val network = connectivityManager.activeNetwork ?: return null
        val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return null
        return getTypeFromCapabilities(capabilities)
    }

    /**
     * 切换应用进程使用的指定类型网络
     * @return 切换是否成功
     */
    fun switchTo(targetType: NetworkQueryHelper.NetworkType): Boolean {
        val targetNetwork = getAvailableNetworks().firstOrNull { it.type == targetType }?.network
            ?: return false

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            connectivityManager.bindProcessToNetwork(targetNetwork)
        } else {
            ConnectivityManager.setProcessDefaultNetwork(targetNetwork)
        }
    }

    /**
     * 注册网络回调，仅监听指定类型的网络变化
     */
    fun registerNetworkCallback(
        interestedTypes: List<NetworkQueryHelper.NetworkType> = listOf(NetworkQueryHelper.NetworkType.CELLULAR, NetworkQueryHelper.NetworkType.ETHERNET),
        callback: (NetworkQueryHelper.NetworkType?) -> Unit
    ) {
        val request = NetworkRequest.Builder().apply {
            interestedTypes.forEach { it.transport?.let { t -> addTransportType(t) } }
        }.build()

        connectivityManager.registerNetworkCallback(
            request,
            object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    val caps = connectivityManager.getNetworkCapabilities(network)
                    callback(getTypeFromCapabilities(caps))
                }

                override fun onLost(network: Network) {
                    callback(null)
                }
            }
        )
    }

    /**
     * 获取所有可用网络信息（仅识别定义在 NetworkType 中的类型）
     */
    private fun getAvailableNetworks(): List<NetworkInfo> {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return emptyList()
        return connectivityManager.allNetworks.mapNotNull { network ->
            val caps = connectivityManager.getNetworkCapabilities(network) ?: return@mapNotNull null
            val type = getTypeFromCapabilities(caps) ?: return@mapNotNull null
            NetworkInfo(network, type)
        }
    }

    /**
     * 从 NetworkCapabilities 推断 NetworkType 类型
     */
    @OptIn(ExperimentalStdlibApi::class)
    private fun getTypeFromCapabilities(capabilities: NetworkCapabilities?): NetworkQueryHelper.NetworkType? {
        capabilities ?: return null
        return NetworkQueryHelper.NetworkType.values().firstOrNull { type ->
            type.transport?.let { capabilities.hasTransport(it) } == true
        }
    }
}